﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.IO;
using System.IO.Compression;
using Ionic.Zip;
using JRFinances.Models;
using System.Globalization;

namespace JRFinances.Business
{
    public class QuotationsManager
    {
        #region Fields

        private static string _basePath = AppDomain.CurrentDomain.BaseDirectory;
        private static string _zipPath = _basePath + "mstcgl.zip";
        private static string _quotationsPath = _basePath + "Quotations";

        #endregion

        #region Public methods

        public static void UpdateQuotations()
        {
            DownloadCurrentFiles();
            UpdateCompanies();
            UpdateQuotationsFromFiles();
        }

        #endregion

        #region Private methods

        private static void DownloadCurrentFiles()
        {
            if (File.Exists(_zipPath))
            {
                File.Delete(_zipPath); // wyczyszczenie starego pliku .zip jesli to konieczne             
            }

            WebClient webClient = new WebClient();
            webClient.DownloadFile("http://bossa.pl/pub/metastock/mstock/mstall.zip", _zipPath); // pobranie nowego pliku z danymi .zip

            if (Directory.Exists(_quotationsPath))
            {
                Directory.Delete(_quotationsPath, true);
            }

            Directory.CreateDirectory(_quotationsPath); // stworzenie pliku na rozpakowane notowania

            using (ZipFile zipFile = ZipFile.Read(_zipPath))
            {
                zipFile.ExtractAll(_quotationsPath); // rozpakowanie notowan
            }
        }

        private static void UpdateCompanies()
        {
            var db = new JRFinancesEntities();

            foreach (string fileName in Directory.GetFiles(_quotationsPath))
            {
                string companyName = Path.GetFileNameWithoutExtension(fileName);
                if (db.Companies.Where(n => n.Name == companyName).Count() == 0) // sprawdzenie czy spolka istnieje juz w bazie
                {
                    Company company = new Company(); { company.Name = Path.GetFileNameWithoutExtension(fileName); }
                    db.Companies.AddObject(company); // dodanie spolki do bazy danych jesli wczesniej nie istniala
                }
            }

            db.SaveChanges();
        }

        private static void UpdateQuotationsFromFiles()
        {
            var db = new JRFinancesEntities();

            DateTime dateOfLastUpdate = db.Quotations.Max(n => n.Date); // data ostatniej aktualizacji notowan

            foreach (string fileName in Directory.GetFiles(_quotationsPath))
            {
                if (File.Exists(fileName))
                {
                    string companyName = Path.GetFileNameWithoutExtension(fileName);
                    Company currentCompany = db.Companies.Single(c => c.Name == companyName); // pobranie obecnie aktualizowanej spolki

                    using (TextReader reader = File.OpenText(fileName))
                    {
                        reader.ReadLine(); // usuniecie naglowkow z pliku
                        string line;

                        while (!string.IsNullOrEmpty(line = reader.ReadLine()))
                        {
                            try
                            {
                                string[] elementsOfLine = line.Split(new char[] { ',' }); // podzial linii z pliku na poszegolne elementy linii

                                if (DateTime.ParseExact(elementsOfLine[1], "yyyyMMdd", CultureInfo.InvariantCulture) > dateOfLastUpdate)
                                {
                                    Quotation quotation = new Quotation();
                                    // dodanie danych z pobranej linii do nowotworzonego notowania
                                    quotation.Company = currentCompany;
                                    quotation.Price = Double.Parse(elementsOfLine[5]);
                                    quotation.Volume = Int32.Parse(elementsOfLine[6]);
                                    quotation.Date = DateTime.ParseExact(elementsOfLine[1], "yyyyMMdd", CultureInfo.InvariantCulture);

                                    db.Quotations.AddObject(quotation);
                                }
                            }
                            catch(Exception ex)
                            {

                            }
                        }

                        db.SaveChanges(); // zapisanie nowych notowan dla danej spolki
                    }
                }
            }
        }


        #endregion
    }
}